package com.ias.agdis_r.manager;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.ias.agdis_r.R;
import com.ias.agdis_r.module.ParameterModel;
import com.ias.agdis_r.netservice.BaseService;
import com.ias.agdis_r.netservice.SendLuggageBarCodeThread;
import com.ias.agdis_r.netservice.SendGpsThread;
import com.ias.agdis_r.netservice.SendMsgThread;
import com.ias.agdis_r.netservice.SendNormalIQRYThread;
import com.ias.agdis_r.netservice.actions.PrivateNetService;
import com.ias.agdis_r.netservice.actions.PublicNetService;
import com.ias.agdis_r.netservice.actions.WifiNetService;
import com.ias.agdis_r.util.S;
import com.ias.agdis_r.util.TestUtil;
import com.ias.agdis_r.util.sdcard.WriteLog;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * 线程管理类 EffectManager.getInstance().ttsPlay(EffectManager.TTS_TYPE_TEMP或BASE
 * 必须用BASE否则会因只用吐司时启动后很快异常挂掉
 * 
 */
public class ThreadManager {

	private static ThreadManager instance = null;// 单例的线程管理器

	private Thread heartThread = null;// 心跳线程
	private Thread IQRYThread = null;// 发送普通IQRY信息线程
	private SendMsgThread sendMsgThread = null;
	private Handler handler = null;
	private Thread GPSThread = null;// 发送普通GPS信息线程
	private boolean heart = false;
	private Map<BaseService, Long> recTimeMap = new HashMap<BaseService, Long>();
	private Map<BaseService, Long> sendTimeMap = new HashMap<BaseService, Long>();
	private long lMsgIntervalTime = 60 * 1000 * 2; // 双倍，否则频繁出现收发超时

	private Vector<String> msgNumberList = new Vector<String>();
	private Map<BaseService, Integer> recCountMap = new HashMap<BaseService, Integer>();
	private Map<BaseService, Integer> sendCountMap = new HashMap<BaseService, Integer>();
	private Map<BaseService, Vector<String>> msgNumberListMap = new HashMap<BaseService, Vector<String>>();
	private Map<BaseService, Boolean> lastPingPackageMap = new HashMap<BaseService, Boolean>();
	private int interval = 6;
	private Context context = DataBaseManager.getInstance().getContext();
	private SendLuggageBarCodeThread sendLuggageBarCodeThread;

	/**
	 * 单例模式
	 * 
	 * @return
	 */
	public static ThreadManager getInstance() {
		if (instance == null) {
			instance = new ThreadManager();
		}
		return instance;
	}

	/**
	 * 初始化Handler
	 */
	public void initHandler() {
		
		handler = new Handler(Looper.myLooper());
	}
	/**
	 * ThreadManager构造时，启动MsgThread
	 */
	public ThreadManager() {
		
		initHandler();
		startSendMsgThread();
	}

	/**
	 * 关闭心跳
	 * **/
	public void stopHeartThread() {
		WriteLog.getInstance().writeLog(context.getString(R.string.TM_1));
		heart = false;
		heartThread = null;
	}

	public synchronized void sendHeat(BaseService service) {
		try {
			if (service != null) {
				int sendCount = sendCountMap.get(service) == null ? 0
						: sendCountMap.get(service);
				EffectManager.getInstance().ttsPlay(
						EffectManager.TTS_TYPE_TEMP,
						context.getString(R.string.TM_2) + (sendCount + 1) + context.getString(R.string.TM_3), false);
				String lastSGOCMessage = MessageManager.getInstance()
						.getSGOCMessage();
				String ms = lastSGOCMessage.substring(2,
						lastSGOCMessage.indexOf(","));
				if (msgNumberList == null) {
					WriteLog.getInstance().writeLog(context.getString(R.string.TM_4));
					return;
				}
				if (msgNumberListMap.get(service) == null) {
					msgNumberList.clear();
				} else {
					msgNumberList.add(ms);
				}
				msgNumberListMap.put(service, msgNumberList);

				service.sendMessage(lastSGOCMessage);
				sendCountMap.put(service, sendCount + 1);
			} else { // 如果上次发送消息没成功则不发再Ping包(等待重连)。
				clearCounter(service);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			WriteLog.getInstance().writeLog(context.getString(R.string.TM_5) + ex.getMessage());
			service.close();
			// 发送消息---网络状态:socket断开
			// Header.getInstance().sendHeaderBroadcast(NetUtils.SENDNETSTATUS,
			// NetUtils.GETADDRESS_SUCCESS, service);
			if (ServiceManage.getInstance().isLastService(service)) {
				stopHeartThread();
			}
			// 最大可能是连接异常
			clearCounter(service);
		}
	}

	public void startHeartThread() {
		if (heart)
			return;
		WriteLog.getInstance().writeLog(context.getString(R.string.TM_6));
		heart = true;
		if (heartThread == null) {
			heartThread = new Thread() {
				@Override
				public void run() {
					while (heart) {
						try {
							sleep(10 * 1000); // sleep ,同时等待PING返回消息
							if ((TestUtil.send_sgoc_count % TestUtil.send_cpu_interval) == 0) {
								TestUtil.send_sgoc_count = 1;
							} else {
								// SGOC发送数量统计+1
								TestUtil.send_sgoc_count = TestUtil.send_sgoc_count + 1;
							}
							BaseService service = ServiceManage.getInstance()
									.getNextUsingService();
							if (service != null) {
								synchronized (this) {
									long sendMsgTime = sendTimeMap.get(service) == null ? 0
											: sendTimeMap.get(service);
									long recMsgTime = recTimeMap.get(service) == null ? 0
											: recTimeMap.get(service);

									if (sendMsgTime - recMsgTime > lMsgIntervalTime) {
										// sysTimeCounter(service);
										EffectManager.getInstance().ttsPlay(
												EffectManager.TTS_TYPE_TEMP,
												context.getString(R.string.TM_7) + lMsgIntervalTime
														+ context.getString(R.string.TM_8), false);
//										WriteLog.getInstance().writeLog(
//												service.getClass()
//														.getSimpleName()
//														+ context.getString(R.string.TM_9));
										service.close();
										// 发送消息---网络状态:socket断开
										// Header.getInstance().sendHeaderBroadcast(NetUtils.SENDNETSTATUS,
										// NetUtils.GETADDRESS_SUCCESS,
										// service);
									}
									if (service.isConnected()) {
										int sendCount = sendCountMap
												.get(service) == null ? 0
												: sendCountMap.get(service);
										int receiveCount = recCountMap
												.get(service) == null ? 0
												: recCountMap.get(service);
										EffectManager.getInstance().ttsPlay(
												EffectManager.TTS_TYPE_TEMP,
												context.getString(R.string.TM_10) + sendCount + context.getString(R.string.TM_11)
														+ receiveCount, false);

										if (sendCount > 0
												&& (isLastPingPakcage(service) || sendCount <= receiveCount)) { // 收发消息数相同
											clearCounter(service);
										} else if (sendCount > 0) {
											if (sendCount == 3) { // 收发数不同，则判断ping
												// 3次如果超过2次没收到则提示连接状态异常
												if (sendCount - receiveCount == 2) {
													Log.v("心跳", "消息收发状况比较差!");
												} else if (sendCount
														- receiveCount > 2) {
													Log.v("心跳", "消息收发状况很差!");
//													WriteLog.getInstance()
//															.writeLog(
//																	service.getClass()
//																			.getSimpleName()
//																			+ context.getString(R.string.TM_12));
													service.close();
													// 发送消息---网络状态:socket断开
													// Header.getInstance().sendHeaderBroadcast(NetUtils.SENDNETSTATUS,
													// NetUtils.GETADDRESS_SUCCESS,
													// service);
												}
												clearCounter(service);
											}
										}
										sendHeat(service);
									}
								}
							}
						} catch (Exception e) {
						}
					}
				}
			};
		}
		if (!heartThread.isAlive())
			heartThread.start();
	}

	public synchronized void updateRecMsgTime(BaseService service) {
		recTimeMap.put(service, System.currentTimeMillis());
	}

	public synchronized void updateSendMsgTime(BaseService service) {
		sendTimeMap.put(service, System.currentTimeMillis());
	}

	public void sysTimeCounter(BaseService service) {
		recTimeMap.put(service, System.currentTimeMillis());
	}

	public void clearCounter(BaseService service) {
		sendCountMap.remove(service);
		recCountMap.remove(service);
		lastPingPackageMap.put(service, false);
		if (msgNumberListMap.get(service) != null) {
			msgNumberListMap.get(service).clear();
		}
	}

	public void stopIQYRThread() {
		if (IQRYThread != null) {
			handler.removeCallbacks(IQRYThread);
			IQRYThread = null;
		}
	}

	public void startIQRYThread() {
		if (IQRYThread == null)
			IQRYThread = new SendNormalIQRYThread(handler);
		handler.post(IQRYThread);
	}

	public void startSendMsgThread() {
		if (sendMsgThread == null)
			sendMsgThread = new SendMsgThread("SendMsgThread");
		sendMsgThread.start();
	}

	public SendMsgThread getSendMsgThread() {
		return sendMsgThread;
	}

	public void stopGPSThread() {
		if (GPSThread != null) {
			handler.removeCallbacks(GPSThread);
			GPSThread = null;
		}
	}

	public void startGPSThread() {
		if (GPSThread == null)
			GPSThread = new SendGpsThread(handler);
		handler.post(GPSThread);
	}

	/**
	 * 开启检查网络线程
	 * **/
	private ConnectSocketThread connectSocket = null;

	public void startConnectSocketThread() {
		if (connectSocket == null) {
			int config_interval = DataBaseManager.getInstance().getInt(
					ParameterModel.INTERVAL, ParameterModel.INTERVAL);
			interval = (config_interval == 0) ? 6 : config_interval;
			connectSocket = new ConnectSocketThread();
			connectSocket.start();
		}
	}

	class ConnectSocketThread extends Thread {
		@Override
		public void run() {
			String name = "";
			while (true) {
				for (final BaseService s : ServiceManage.getInstance()
						.getServiceArray()) {
					if (s.getClass().equals(WifiNetService.class)) {
						name = context.getString(R.string.net_wifi);
					}
					if (s.getClass().equals(PrivateNetService.class)) {
						name = context.getString(R.string.net_private);
					}
					if (s.getClass().equals(PublicNetService.class)) {
						name = context.getString(R.string.net_public);
					}
					String ip = s.getLocalIpAddress();
					// 对于WIFI的正在连接状态进行判断
					if (s.connectting()) {
						System.out.println(name + "网络正在连接");

						EffectManager.getInstance().ttsPlay(
								EffectManager.TTS_TYPE_TEMP, name + context.getString(R.string.TM_13), false);
						// 判断SOCKET是否正在连接
					} else if (!s.finishConnect()) {
						System.out.println(name + "SOCKET正在连接");
						EffectManager.getInstance().ttsPlay(
								EffectManager.TTS_TYPE_TEMP, name + context.getString(R.string.TM_14), false);
					} else if (S.isNotEmpty(ip) && !s.isConnected()) {

						System.out.println("开始检查网络");
						EffectManager.getInstance().ttsPlay(
								EffectManager.TTS_TYPE_TEMP, name + context.getString(R.string.TM_15), false);
						s.checkAvailable();
					}
				}
				try {
					Thread.sleep(interval * 1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public void stopAllThread() {
		stopHeartThread();
		stopIQYRThread();
		stopGPSThread();
		// stopAllReceiveMessageThread();
	}

	public void resleepForIQRYThread(long mill) {
		handler.removeCallbacks(IQRYThread);
		handler.postDelayed(IQRYThread, mill);
	}

	public Thread getHeartThread() {
		return heartThread;
	}

	public Thread getIQRYThread() {
		return IQRYThread;
	}

	private boolean isLastPingPakcage(BaseService service) {
		return lastPingPackageMap.get(service);
	}

	public synchronized void checkMessageNumber(BaseService service,
			String sgrpNumber) {
		// lastPingPackage = false;
		lastPingPackageMap.put(service, false);
		msgNumberList = msgNumberListMap.get(service);
		if (null == msgNumberList) {
			WriteLog.getInstance().writeLog(context.getString(R.string.TM_16));
			return;
		}
		for (int i = msgNumberList.size(); i > 0; i--) {
			String nbr = msgNumberList.get(i - 1);
			if (nbr != null && nbr.equals(sgrpNumber)) {
				int nCount = recCountMap.get(service) == null ? 0 : recCountMap
						.get(service);
				recCountMap.put(service, nCount + 1);

				if (i == msgNumberList.size()) {
					// lastPingPackage = true;
					lastPingPackageMap.put(service, true);
				}
				msgNumberList.remove(nbr);
				break;
			}
		}
	}

	public void stopSendLuggageBarCodeThread(){
		WriteLog.getInstance().writeLog("stopSendLuggageBarCodeThread:"+(sendLuggageBarCodeThread == null));
		if (sendLuggageBarCodeThread != null) {
			handler.removeCallbacks(sendLuggageBarCodeThread);
			sendLuggageBarCodeThread = null;
		}
	}

	public void startSendLuggageBarCodeThread(){
		WriteLog.getInstance().writeLog("startSendLuggageBarCodeThread:"+(sendLuggageBarCodeThread == null));
		if (sendLuggageBarCodeThread == null) {
			sendLuggageBarCodeThread = new SendLuggageBarCodeThread(handler);
			handler.post(sendLuggageBarCodeThread);
		}
	}

	public void reSleepSendLuggageBarCodeThread(long mill) {
		WriteLog.getInstance().writeLog("reSleepSendLuggageBarCodeThread,mill:"+mill);
		handler.removeCallbacks(sendLuggageBarCodeThread);
		handler.postDelayed(sendLuggageBarCodeThread, mill);
	}
}
